package com.start.common.std;

import com.start.common.event.StartBaseEvent;
import com.start.common.exceptions.StartBusException;
import com.start.common.tools.StartMapTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 基础分发器定义
 *
 * @param <T>
 */
@Slf4j
public abstract class StartEventDispatcherListener<T extends StartEventDispatcherListener, E extends StartBaseEvent> extends StartBaseSingleton<T> implements StartBaseEvent {
    private ConcurrentHashMap<String, List<E>> dispatcherMap;
    public static final String GROUP_PREFIX = "group_type";
    public static final String UNION_KEY_PREFIX = "union_key";
    public static final String GLOBAL_PREFIX = "global_type";
    public static final String GLOBAL_KEY = "global_key";

    /**
     * 调用初始化函数
     */
    @Override
    public final void init() {
        dispatcherMap = new ConcurrentHashMap<>();
        initDispatcher();
    }

    /**
     * 添加事件
     *
     * @param prefix 前缀
     * @param key    唯一标识
     * @param event  事件对象
     */
    public void addEvent(String prefix, String key, E event) {
        if (StringUtils.isAllBlank(prefix)) {
            throw new StartBusException("prefix cannot be null or empty");
        }
        if (StringUtils.isAllBlank(key)) {
            throw new StartBusException("key cannot be null or empty");
        }
        if (event == null) {
            throw new StartBusException("event cannot be null or empty");
        }

        if (StringUtils.isAllBlank(event.SPLIT())||!key.contains(event.SPLIT())) {
            String fKey = prefix + ":" + key;
            List<E> listEvents = StartMapTools.getListByKey(dispatcherMap, fKey);
            if (listEvents.contains(event)) {
                return;
            }
            listEvents.add(event);
            return;
        }
        String[] tables = key.split(event.SPLIT());
        for (String tab : tables) {
            String t = tab.trim();
            if (StringUtils.isAllBlank(t)) {
                log.warn("TableDataListener:" + event.getClass().getName() + " tableName contain Empty tableName");
                continue;
            }
            addEvent(prefix, t, event);
        }
    }



    /**
     * 初始化分发器
     */
    protected abstract void initDispatcher();

    /**
     * @param prefix
     * @param key    唯一表示
     * @return
     */
    public List<E> getEvents(String prefix, String key) {
        if (StringUtils.isAllBlank(prefix)) {
            throw new StartBusException("prefix cannot be null or empty");
        }
        if (StringUtils.isAllBlank(key)) {
            throw new StartBusException("key cannot be null or empty");
        }
        String fKey = prefix + ":" + key;
        return StartMapTools.getListByKey(dispatcherMap, fKey);
    }
}
